﻿local MyData = {};

function StatReport_SetButtonIcon(self, Myclass)
	self.icon = self:CreateTexture(nil, "OVERLAY")
	self.icon:SetWidth(24);
	self.icon:SetHeight(24);
	self.icon:SetPoint("LEFT", self, 0, 0)
	self.icon:SetTexture("Interface\\WorldStateFrame\\Icons-Classes")
	local coords = CLASS_BUTTONS[Myclass]
	self.icon:SetTexCoord(coords[1],coords[2],coords[3],coords[4])
	self.icon:Show()
end

function StatReport_ChatFrameEditBoxMSG(msg)
	local ExistMSG = ChatFrameEditBox:GetText() or "";
	if IsShiftKeyDown() then
		ChatFrameEditBox:SetText(msg);
		ChatEdit_SendText(ChatFrameEditBox);
		ChatFrameEditBox:SetText(ExistMSG);
		if ExistMSG == "" then
			ChatFrameEditBox:Hide();
		end
		return;
	end
	if IsAltKeyDown() then
		ChatFrameEditBox:SetText(msg);
		ChatEdit_SendText(ChatFrameEditBox);
		ChatEdit_SendText(ChatFrameEditBox);
		ChatFrameEditBox:SetText(ExistMSG);
		if ExistMSG == "" then
			ChatFrameEditBox:Hide();
		end
		return;
	end
	if ChatFrameEditBox:IsShown() then
		ChatFrameEditBox:Insert(msg);
	else
		ChatFrameEditBox:SetText(ExistMSG..msg);
		ChatFrameEditBox:Show();
--		ChatFrameEditBox:HighlightText();
	end
end

function StatReport_OnClick(self,arg1)
	if arg1=="LeftButton" then
		local msg = "";
		StatReport_UpdateMyData();
		msg = msg..MyData.CLASS;
		msg = msg..StatReport_Strings_COMMA;
		msg = msg..MyData.TKEY..StatReport_Strings_TALENT..MyData.TDATA;
		msg = msg..StatReport_Strings_COMMA;
		msg = msg..StatReport_Strings_ILVL..MyData.ILVL;

		msg = msg..StatReport_Strings_COMMA;
		if MyData.CLASS_EN == "MAGE" or MyData.CLASS_EN == "WARLOCK" then
			msg = msg..StatReport_GetSpellText();
		end
		if MyData.CLASS_EN == "ROGUE" then
			msg = msg..StatReport_GetMeleeText();
		end
		if MyData.CLASS_EN == "HUNTER" then
			msg = msg..StatReport_GetRangedText();
		end
		if MyData.CLASS_EN == "DRUID" then
			if MyData.TKEY == GetTalentTabInfo(1) then
				msg = msg..StatReport_GetSpellText();
			elseif MyData.TKEY == GetTalentTabInfo(2) then
				if MyData.DODGE > 30 then
					msg = msg..StatReport_GetTankText();
				else
					msg = msg..StatReport_GetMeleeText();
				end
			elseif MyData.TKEY == GetTalentTabInfo(3) then
				msg = msg..StatReport_GetHealText();
			else
				msg = msg..StatReport_GetMeleeText();
			end
		end
		if MyData.CLASS_EN == "SHAMAN" then
			if MyData.TKEY == GetTalentTabInfo(1) then
				msg = msg..StatReport_GetSpellText();
			elseif MyData.TKEY == GetTalentTabInfo(2) then
				msg = msg..StatReport_GetMeleeText();
			elseif MyData.TKEY == GetTalentTabInfo(3) then
				msg = msg..StatReport_GetHealText();
			else
				msg = msg..StatReport_GetMeleeText();
			end
		end
		if MyData.CLASS_EN == "PALADIN" then
			if MyData.TKEY == GetTalentTabInfo(1) then
				msg = msg..StatReport_GetHealText();
			elseif MyData.TKEY == GetTalentTabInfo(2) then
				msg = msg..StatReport_GetTankText();
			elseif MyData.TKEY == GetTalentTabInfo(3) then
				msg = msg..StatReport_GetMeleeText();
			else
				msg = msg..StatReport_GetMeleeText();
			end
		end
		if MyData.CLASS_EN == "PRIEST" then
			if MyData.TKEY == GetTalentTabInfo(1) then
				msg = msg..StatReport_GetSpellAndHealText();
			elseif MyData.TKEY == GetTalentTabInfo(2) then
				msg = msg..StatReport_GetHealText();
			elseif MyData.TKEY == GetTalentTabInfo(3) then
				msg = msg..StatReport_GetSpellText();
			else
				msg = msg..StatReport_GetSpellText();
			end
		end
		if MyData.CLASS_EN == "WARRIOR" then
			if MyData.TKEY == GetTalentTabInfo(1) then
				msg = msg..StatReport_GetMeleeText();
			elseif MyData.TKEY == GetTalentTabInfo(2) then
				msg = msg..StatReport_GetMeleeText();
			elseif MyData.TKEY == GetTalentTabInfo(3) then
				msg = msg..StatReport_GetTankText();
			else
				msg = msg..StatReport_GetMeleeText();
			end
		end
		if MyData.CLASS_EN == "DEATHKNIGHT" then
			if (MyData.DODGE + MyData.PARRY) > 35 then
				msg = msg..StatReport_GetTankText();
			else
				msg = msg..StatReport_GetMeleeText();
			end
		end

		if MyData.CRDEF > (200*(MyData.LV/70)) then
			msg = msg..StatReport_Strings_COMMA;
			msg = msg..MyData.CRDEF..StatReport_Strings_CRDEF;
		end

		if IsShiftKeyDown() or IsAltKeyDown() then
			StatReport_Print(msg);
			return;
		end
		StatReport_ChatFrameEditBoxMSG(msg);
	end
	if arg1=="RightButton" then
		GameTooltip:Hide();
		StatReport_DropDown.point = "BOTTOMLEFT";
		StatReport_DropDown.relativePoint = "BOTTOMRIGHT";
		ToggleDropDownMenu(1, nil, StatReport_DropDown);
	end
end

function StatReport_GetSpellText()
	local text = "";
	text = text..MyData.SSP..StatReport_Strings_SSP;
	text = text..StatReport_Strings_COMMA;
	text = text..MyData.SHIT..StatReport_Strings_HIT;
	text = text..StatReport_Strings_COMMA;
	text = text..format("%.1f%%", MyData.SCRIT)..StatReport_Strings_CRIT;
	text = text..StatReport_Strings_COMMA;
	text = text..MyData.SHASTE..StatReport_Strings_HASTE;
	text = text..StatReport_Strings_COMMA;
	text = text..MyData.MP..StatReport_Strings_MP;
	return text;
end

function StatReport_GetHealText()
	local text = "";
	text = text..MyData.SHP..StatReport_Strings_SHP;
	text = text..StatReport_Strings_COMMA;
	text = text..format("%.1f%%", MyData.SCRIT)..StatReport_Strings_CRIT;
	text = text..StatReport_Strings_COMMA;
	text = text..MyData.SHASTE..StatReport_Strings_HASTE;
	text = text..StatReport_Strings_COMMA;
	text = text..MyData.MP..StatReport_Strings_MP;
	text = text..StatReport_Strings_COMMA;
	text = text..MyData.SMR.."/"..StatReport_Strings_SMR;
	return text;
end

function StatReport_GetSpellAndHealText()
	local text = "";
	text = text..MyData.SSP..StatReport_Strings_SSP;
	text = text..StatReport_Strings_COMMA;
	text = text..MyData.SHP..StatReport_Strings_SHP;
	text = text..StatReport_Strings_COMMA;
	text = text..MyData.SHIT..StatReport_Strings_HIT;
	text = text..StatReport_Strings_COMMA;
	text = text..format("%.1f%%", MyData.SCRIT)..StatReport_Strings_CRIT;
	text = text..StatReport_Strings_COMMA;
	text = text..MyData.SHASTE..StatReport_Strings_HASTE;
	text = text..StatReport_Strings_COMMA;
	text = text..MyData.MP..StatReport_Strings_MP;
	text = text..StatReport_Strings_COMMA;
	text = text..MyData.SMR.."/"..StatReport_Strings_SMR;
	return text;
end

function StatReport_GetMeleeText()
	local text = "";
	text = text..MyData.MAP..StatReport_Strings_AP;
	text = text..StatReport_Strings_COMMA;
	text = text..MyData.MHIT..StatReport_Strings_HIT;
	text = text..StatReport_Strings_COMMA;
	text = text..format("%.1f%%", MyData.MCRIT)..StatReport_Strings_CRIT;
	text = text..StatReport_Strings_COMMA;
	text = text..MyData.MEXPER..StatReport_Strings_EXPER;
	return text;
end

function StatReport_GetRangedText()
	local text = "";
	text = text..MyData.RAP..StatReport_Strings_AP;
	text = text..StatReport_Strings_COMMA;
	text = text..MyData.RHIT..StatReport_Strings_HIT;
	text = text..StatReport_Strings_COMMA;
	text = text..format("%.1f%%", MyData.RCRIT)..StatReport_Strings_CRIT;
	return text;
end

function StatReport_GetTankText()
	local text = "";
	text = text..MyData.HP..StatReport_Strings_HP;
	text = text..StatReport_Strings_COMMA;
	text = text..MyData.DEF..StatReport_Strings_DEF;
	text = text..StatReport_Strings_COMMA;
	text = text..format("%.1f%%", MyData.DODGE)..StatReport_Strings_DODGE;
	text = text..StatReport_Strings_COMMA;
	text = text..format("%.1f%%", MyData.PARRY)..StatReport_Strings_PARRY;
	text = text..StatReport_Strings_COMMA;
	text = text..format("%.1f%%", MyData.BLOCK)..StatReport_Strings_BLOCK;
	text = text..StatReport_Strings_COMMA;
	text = text..MyData.ARMOR..StatReport_Strings_ARMOR;
	return text;
end

function StatReport_UpdateMyData()
	MyData.Name = UnitName("player");							--名称
	MyData.LV = UnitLevel("player");							--等级
	MyData.CLASS, MyData.CLASS_EN = UnitClass("player");		--职业
	MyData.HP = UnitHealthMax("player");						--生命值
	MyData.MP = UnitManaMax("player");							--法力值
	MyData.TKEY, MyData.TDATA = StatReport_TalentData();		--天赋
	MyData.ILVL = StatReport_UnitItem_ilvl_AVG("player");		--综合装备等级
	--基础属性
	MyData.STR = UnitStat("player", 1);							--力量
	MyData.AGI = UnitStat("player", 2);							--敏捷
	MyData.STA = UnitStat("player", 3);							--耐力
	MyData.INT = UnitStat("player", 4);							--智力
	MyData.SPI = UnitStat("player", 5);							--精神
	--近战
	MyData.MAP = StatReport_UnitAttackPower();					--强度
	MyData.MHIT = GetCombatRating(6);							--命中等级
	MyData.MCRIT = GetCritChance();								--爆击率%
	MyData.MEXPER = GetExpertise();								--精准
	--远程
	MyData.RAP = StatReport_UnitRangedAttackPower();			--强度
	MyData.RHIT = GetCombatRating(7);							--命中等级
	MyData.RCRIT = GetRangedCritChance();						--爆击率%
	--法术
	MyData.SSP = StatReport_GetSpellBonusDamage();				--伤害加成
	MyData.SHP = GetSpellBonusHealing();						--治疗加成
	MyData.SHIT = GetCombatRating(8);							--命中等级
	MyData.SCRIT = StatReport_GetSpellCritChance();				--爆击率
	MyData.SHASTE = GetCombatRating(20);						--急速等级
	MyData.SMR = floor(GetManaRegen()*5);						--法力回复（每5秒）
	--防御
	_,_,MyData.ARMOR = UnitArmor("player");						--护甲
	MyData.DEF = StatReport_UnitDefense();						--防御
	MyData.DODGE = GetDodgeChance();							--躲闪%
	MyData.PARRY = GetParryChance();							--招架%
	MyData.BLOCK = GetBlockChance();							--格挡%
	MyData.CRDEF = GetCombatRating(15);							--韧性
end

function StatReport_TalentData()
	local name1,_,pointsSpent1 = GetTalentTabInfo(1);
	local name2,_,pointsSpent2 = GetTalentTabInfo(2);
	local name3,_,pointsSpent3 = GetTalentTabInfo(3);
	local nameKey = StatReport_Strings_NONE;
	local TalentStat = "";
	if not(pointsSpent1 == 0 and pointsSpent2 == 0 and pointsSpent3 == 0) then
		local tmpname, temppointsSpent;
		tmpname = ((pointsSpent1 > pointsSpent2) and name1) or name2;
		temppointsSpent = ((pointsSpent1 > pointsSpent2) and pointsSpent1) or pointsSpent2;
		tmpname = ((temppointsSpent > pointsSpent3) and tmpname) or name3;
		nameKey = tmpname;
	end
	if nameKey ~= StatReport_Strings_NONE then
		TalentStat = ("(%s/%s/%s)"):format(pointsSpent1, pointsSpent2, pointsSpent3);
	end
	return nameKey, TalentStat;
end

function StatReport_UnitAttackPower()
	local base, posBuff, negBuff = UnitAttackPower("player");
	return floor(base + posBuff + negBuff);
end

function StatReport_UnitRangedAttackPower()
	local base, posBuff, negBuff = UnitRangedAttackPower("player");
	return floor(base + posBuff + negBuff);
end

function StatReport_GetSpellBonusDamage()
	local SSP = GetSpellBonusDamage(2);
	for i=3, 7 do
		SSP = max(SSP, GetSpellBonusDamage(i));
	end
	return floor(SSP);
end

function StatReport_GetSpellCritChance()
	local SCRIT = GetSpellCritChance(2);
	for i=3, 7 do
		SCRIT = max(SCRIT, GetSpellCritChance(i));
	end
	return SCRIT;
end

function StatReport_UnitDefense()
	local baseDEF, posDEF = UnitDefense("player");
	return floor(baseDEF + posDEF);
end

function StatReport_UnitItem_ilvl_AVG(unit)
	local _, uc = UnitClass(unit);
	local ul = UnitLevel(unit);
	--品质折算系数
	local qualitypara = {
		[0]		= 0.0,			--0：灰色
		[1]		= 0.1,			--1：白色
		[2]		= 0.6,			--2：绿色
		[3]		= 0.8,			--3：蓝色
		[4]		= 1.0,			--4：紫色
		[5]		= 1.05,			--5：橙色
		[6]		= 1.15,			--6：红色
		[7]		= 1.0,			--7：金色
	};
	--装备级别加权系数默认值：法系
	local slotpara = {
		[1]		= 3.5,			--1：头
		[2]		= 2,			--2：颈
		[3]		= 2.5,			--3：肩
		[4]		= 0,			--4：衬衣
		[5]		= 3.7,			--5：胸
		[6]		= 2.3,			--6：腰带
		[7]		= 3.5,			--7：腿
		[8]		= 2.4,			--8：脚
		[9]		= 1.6,			--9：手腕
		[10]	= 2.5,			--10：手套
		[11]	= 2.1,			--11：手指1
		[12]	= 2.1,			--12：手指2
		[13]	= 2,			--13：饰品1
		[14]	= 2,			--14：饰品2
		[15]	= 1.8,			--15：背
		[16]	= 6,			--16：主手
		[17]	= 2,			--17：副手
		[18]	= 1,			--18：远程武器
		[19]	= 0,			--19：战袍
	};
	if uc == "HUNTER" then
		slotpara[16] = 3;
		slotpara[17] = 1;
		slotpara[18] = 5;
	elseif uc == "WARRIOR" then
		if MyData.TKEY == GetTalentTabInfo(3) then
			slotpara[16] = 3.5;
			slotpara[17] = 4.5;
			slotpara[18] = 1;
		else
			slotpara[16] = 5;
			slotpara[17] = 3;
			slotpara[18] = 1;
		end
	elseif uc == "ROGUE" or uc == "DEATHKNIGHT" then
		slotpara[16] = 5;
		slotpara[17] = 3;
		slotpara[18] = 1;
	elseif uc == "SHAMAN" then
		if MyData.TKEY == GetTalentTabInfo(2) then
			slotpara[16] = 5;
			slotpara[17] = 3;
			slotpara[18] = 1;
		end
	elseif uc == "PALADIN" then
		if MyData.TKEY == GetTalentTabInfo(2) then
			slotpara[16] = 3.5;
			slotpara[17] = 4.5;
			slotpara[18] = 1;
		end
	end
	local quality, iLevel;
	local itemcount = 0;
	local levelcount = 0;
	local paracount = 0;
	for i=1, 18 ,1 do
		if i~=4 then
			local link = GetInventoryItemLink(unit, i);
			if (link) then
				_, _, quality, iLevel = GetItemInfo(link);
				if(quality >=1 and quality <=7) then
					if (quality == 7) and (iLevel < ul*2) then
						iLevel = (ul*ul*ul)/2400;
					end
					itemcount = itemcount + 1;
					levelcount = levelcount + iLevel*qualitypara[quality]*slotpara[i];
					paracount = paracount + slotpara[i];
				end
			end
		end
	end
	return floor((levelcount/paracount) + 0.5);
end

function StatReport_Print(msg)
	if DEFAULT_CHAT_FRAME then
		DEFAULT_CHAT_FRAME:AddMessage(tostring(msg), 1, 0.9, 0.4);
	end
end

function StatReport_DropDown_OnLoad(self)
	UIDropDownMenu_Initialize(self, StatReport_DropDown_Initialize, "MENU");
end

function StatReport_DropDown_Initialize()
	local info = UIDropDownMenu_CreateInfo();
	info.text = StatReport_DropDown_TITLE;
	info.notClickable = 1;
	info.isTitle = 1;
	info.notCheckable = 1;
	UIDropDownMenu_AddButton(info);
	for key, value in pairs(StatReport_WORDS_DATA) do
		info = UIDropDownMenu_CreateInfo();
		info.text = value;
		info.value = key;
		info.notCheckable = 1;
		info.func = StatReport_InsWords;
		UIDropDownMenu_AddButton(info);
	end
end

function StatReport_InsWords(self)
	local id = self.value;
	StatReport_ChatFrameEditBoxMSG(StatReport_WORDS_DATA[id]);
end
